home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / m / tan.c < prev    next >
C/C++ Source or Header  |  1988-07-11  |  2KB  |  59 lines

  1. /*
  2.  * Copyright (c) 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  *
  12.  * All recipients should regard themselves as participants in an ongoing
  13.  * research project and hence should feel obligated to report their
  14.  * experiences (good or bad) with these elementary function codes, using
  15.  * the sendbug(8) program, to the authors.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)tan.c    5.2 (Berkeley) 4/29/88";
  20. #endif /* not lint */
  21.  
  22. #include "trig.h"
  23. double
  24. tan(x) 
  25. double x;
  26. {
  27.     double a,z,ss,cc,c;
  28.     int k;
  29.  
  30.     if(!finite(x))        /* tan(NaN) and tan(INF) must be NaN */
  31.         return x-x;
  32.     x = drem(x,PI);            /* reduce x into [-PI/2, PI/2] */
  33.     a = copysign(x,one);        /* ... = abs(x) */
  34.     if (a >= PIo4) {
  35.         k = 1;
  36.         x = copysign(PIo2-a,x);
  37.     }
  38.     else {
  39.         k = 0;
  40.         if (a < small) {
  41.             big+a;
  42.             return x;
  43.         }
  44.     }
  45.     z = x*x;
  46.     cc = cos__C(z);
  47.     ss = sin__S(z);
  48.     z *= half;            /* Next get c = cos(x) accurately */
  49.     c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc));
  50.     if (k == 0)
  51.         return x+(x*(z-(cc-ss)))/c;    /* ... sin/cos */
  52. #ifdef national
  53.     else if (x == zero)
  54.         return copysign(fmax,x);    /* no inf on 32k */
  55. #endif    /* national */
  56.     else
  57.         return c/(x+x*ss);        /* ... cos/sin */
  58. }
  59.